前幾天我們逐步建立了一個最小 Agent 架構。
目前系統已經有:
接下來很容易出現一個問題。
每當我們想加入新功能,就直接修改 Agent Loop。
想記錄工具使用,就在 Loop 裡加 Log。
想阻擋危險操作,就在 Loop 裡加條件判斷。
想在任務完成前執行驗證,就再加入一段流程。
想記錄 Token、延遲與成本,又繼續修改核心程式。
最後,原本簡單的 Loop 會同時負責:
每一個功能單獨看都合理。
但如果全部寫進核心 Loop,系統會越來越難理解、測試與修改。
今天要介紹一個常見的擴充方法:
Hooks 與 Lifecycle Events。
它們讓我們可以在 Agent 執行的特定時間點插入自訂行為,而不需要一直改動 Loop 本身。
Hook 是一個預先定義好的擴充點。
Agent 執行到某個階段時,Harness 會觸發對應事件,讓外部邏輯在那個時間點執行。
常見事件包括:
這些時間點可以稱為 Lifecycle Events。
Hook 則是掛在 Event 上的處理邏輯。
可以把它理解成:
Lifecycle Event 定義「什麼時候」,Hook 定義「要做什麼」。
例如,工具執行前可以觸發:
工具執行後則可以:
核心 Loop 只需要負責觸發事件。
具體功能則由各自的 Hook 處理。
假設一開始只有一個需求:
在每次工具執行前記錄工具名稱。
直接加進 Loop 看起來非常簡單。
但很快又會出現:
如果所有邏輯都在同一個函式中,會造成幾個問題。
你很難快速看出 Agent 真正的控制流程。
到底是什麼讓它繼續?
又是什麼讓它停止?
答案會被淹沒在大量周邊邏輯中。
即使只是加入一個 Log,也可能意外影響錯誤處理、Retry 或停止條件。
要測試一個小功能,卻必須啟動整個 Agent。
開發環境可能需要完整 Trace。
Production 需要嚴格 Security Hook。
Evaluation 環境則需要保存每一輪輸入輸出。
如果全部寫死在 Loop,就會出現大量環境判斷。
Hooks 的目的,就是把這些跨模組功能拆出去。
不同 Framework 的命名不一定相同,但概念通常接近。
任務開始時觸發。
適合:
每次呼叫模型前觸發。
適合:
模型回應後觸發。
適合:
工具真正執行前觸發。
適合:
工具執行完成後觸發。
適合:
Agent 準備停止時觸發。
適合:
任務確定結束後觸發。
適合:
Hooks 的價值不只是讓「任何功能都能插入」。
而是每個擴充功能都有清楚的執行時機。
Hooks 可以大致分成三類。
只觀察,不修改 Agent 行為。
例如:
這類 Hook 風險最低。
即使非關鍵 Metrics 暫時失敗,通常也不應該讓主要任務停止。
修改輸入或輸出。
例如:
這類 Hook 會改變 Agent 看到的資訊,所以必須留下 Trace。
否則 Debug 時會出現一個問題:
為什麼工具原始輸出和模型實際看到的內容不同?
阻擋、暫停或改變流程。
例如:
這類 Hook 最強,也最危險。
因為它不只是觀察,而是直接改變 Agent 的控制流程。
如果 Hook 只能觀察,回傳值可能不重要。
但如果 Hook 可以控制流程,就需要定義清楚結果。
例如:
不要把所有政策決定都表示成 Exception。
因為 Exception 通常表示程式發生非預期錯誤。
但 Permission Hook 回傳 Block,可能是完全正常的系統行為。
Hook Exception 代表 Hook 可能壞了,Hook Block 代表 Hook 正常做出阻擋決定。
兩者不應混為一談。
假設工具執行前有三個 Hook:
不同順序可能產生不同結果。
如果先記錄再 Redact,Audit Log 可能包含 Secret。
如果先修改參數再檢查 Permission,Policy 看到的是修改後請求。
如果 Permission 已經拒絕,後續 Hook 是否還需要執行?
因此 Hook System 必須定義:
最簡單的方式是設定明確 Priority。
例如:
順序應該是架構的一部分,而不是依賴註冊先後的巧合。
Hook 自己也可能出錯。
例如:
不同 Hook 的失敗策略應該不同。
Hook 失敗,但主要任務繼續。
適合:
Hook 失敗,操作必須停止。
適合:
記錄 Hook 錯誤,但不阻擋任務。
適合不影響安全的觀察型 Hook。
因此每個 Hook 都應該聲明:
這是關鍵控制,還是附加觀察?
否則一個 Metrics Service 故障,可能讓所有 Agent 停擺。
反過來,Permission Hook 故障後仍然繼續,也可能造成安全問題。
Hooks 很方便,所以也很容易被濫用。
任何不想放進 Loop 的邏輯,都可能被塞進 Hook。
最後 Hook System 反而變成另一個看不見的複雜流程。
這些通常是 Cross-cutting Concerns,也就是會跨越多個工具或流程的共同能力。
例如:
這是主要 Workflow,不應該偷偷藏在 Hooks 中。
Hook 適合擴充控制平面,不適合隱藏主要業務流程。
Hook 與 Middleware 很像,但思考方式略有不同。
在某個事件發生時觸發。
例如:
適合事件導向的擴充。
通常包住一段完整執行流程。
適合:
實務上兩者常會混合。
重點不在名稱,而在責任是否清楚。
Hooks 很適合收集 Evaluation Data。
模型呼叫後可以記錄:
工具執行後可以記錄:
任務結束後可以記錄:
這些資料可以回答:
架構機制是否有效,最後還是要用 Evaluation 證明。
第一版不需要支援所有事件。
可以先從四個最有價值的 Event 開始:
再定義三種行為:
每個 Hook 至少要有:
這樣已經足以支援:
等到真的有 Failure Mode,再加入 Agent Start、Agent Stop 或 Approval Resume 等更細事件。
Day 4 的系統已經有 Permission、Approval 和 Sandbox。
但這些邏輯仍然可能直接寫在 Agent Loop 裡。
今天加入:
因此,我們可以在不一直修改核心 Loop 的情況下,加入:
核心 Loop 保持簡單。
擴充行為則可以獨立開關、測試與組合。
Agent Loop 應該負責核心控制流程。
它不應該同時承擔每一個安全、觀察、通知與商業需求。
Hooks 提供明確的 Lifecycle Events,讓系統能在特定時機加入自訂行為。
最重要的原則是:
核心 Loop 決定 Agent 如何前進,Hooks 負責在關鍵節點觀察、修改或阻擋。
但 Hooks 也不能無限制使用。
如果主要任務流程全部藏進 Hook,系統只會從「複雜的 Loop」變成「看不見的複雜 Hook」。
下一篇會進入 Planning:
Agent 為什麼需要先拆解任務?一份看起來完整的計畫,真的能讓執行更可靠嗎?
完整系列與範例收錄於:https://github.com/hardness1020/awesome-agent-architecture